import chunk, nbt, utility
import streams, times
import zip/zlib

type
  Region* = array[32, array[32, Chunk]]

proc writeRegion*(stream: Stream, region: Region) =
  var 
    contentStream = newStringStream()
    currentOffset = 2'u32
  for chunks in region:
    for chunk in chunks:
      if chunk == nil:
        stream.write 0'u32
      else:
        var chunkStream = newStringStream()
        chunkStream.writeNbt chunk
        chunkStream.setPosition 0
        let
          data = chunkStream.readAll
          uncompressedLen = data.len.Ulongf
        var
          uncompressed = data.Pbytef
          compressed: Pbytef
          compressedLen: Ulongf
        chunkStream.close
        discard compress(compressed, compressedLen.addr, uncompressed, uncompressedLen)
        let
          totalLength: uint32 = compressedLen + 5
          indicatedLength: uint32 = compressedLen + 1
          padLength = (4096'u32 - totalLength mod 4096) mod 4096
          lengthInSectors = (totalLength + padLength) div 4096
        contentStream.write indicatedLength.toBigEndian
        contentStream.write 2'u8
        contentStream.write compressed
        for _ in 0..<padLength:
          contentStream.write 0'u8
        stream.write ((currentOffset and 0xff0000) shr 16).uint8
        stream.write ((currentOffset and 0xff00) shr 8).uint8
        stream.write (currentOffset and 0xff).uint8
        stream.write lengthInSectors.uint8
        currentOffset += lengthInSectors
  let timestamp = getTime().toUnix.uint32.toBigEndian
  for _ in 0..<1024:
    stream.write timestamp
  contentStream.flush
  contentStream.setPosition 0
  stream.write contentStream.readAll
